package com.lottery.material.util;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.lottery.material.common.Constants;
import com.lottery.material.enumeration.ResultEnum;
import com.lottery.material.jedis.JedisClient;
import com.lottery.material.pojo.portaluser.PortalUserInfo;
import com.lottery.material.resolver.CustomException;
import com.lottery.material.service.portal.user.PortalUserInfoService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.servlet.http.HttpServletRequest;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Description:    参数处理工具类
 * Author:         sunny
 * CreateDate:     2019-04-13 下午 3:58
 */
public class ParameterUtil {

    private static final Logger logger = LoggerFactory.getLogger(ParameterUtil.class);

    /**
     * description: 请求参数解析
     * author sunny
     * createDate 2019-04-13 下午 4:33
     * @param request
     * @param reqParamMap
     * @return
     */
    public static boolean analyticParameter(HttpServletRequest request, Map<String, String> reqParamMap) {
        try {
            Map<String, Object> jsonMap;
            String param = HttpClientUtil.getRequestContent(request);
            if (StringUtils.isNotBlank(param)) {
                if (param.contains("&") || param.contains("=")) {//key=value&key=value的形式
                    jsonMap = MapUtil.getToMap(param);
                } else if (param.contains("{") && param.contains("}")) {//JSON格式
                    jsonMap = FastjsonUtil.jsonObjectString2Map(param);
                } else {
                    logger.info("请求参数格式不符合要求");
                    return true;
                }
                if (null != jsonMap && !jsonMap.isEmpty()) {
                    for (Map.Entry<String, Object> entry : jsonMap.entrySet()) {
                        String key = entry.getKey();
                        String value = String.valueOf(entry.getValue());
                        reqParamMap.put(key, value);
                    }
                }
            }else{
                // 参数Map
                Map properties = request.getParameterMap();
                if(properties == null || properties.size() == 0){
                    logger.info("请求参数格式不符合要求");
                    return true;
                }

                Iterator entries = properties.entrySet().iterator();
                Map.Entry entry;
                String name;
                String value = "";
                while (entries.hasNext()) {
                    entry = (Map.Entry) entries.next();
                    name = (String) entry.getKey();
                    Object valueObj = entry.getValue();
                    if(null == valueObj){
                        value = "";
                    }else if(valueObj instanceof String[]){
                        String[] values = (String[])valueObj;
                        for(int i=0;i<values.length;i++){
                            value = values[i] + ",";
                        }
                        value = value.substring(0, value.length()-1);
                    }else{
                        value = valueObj.toString();
                    }
                    reqParamMap.put(name, StringUtil.urlCodeToStr(value));
                }
            }
        } catch (Exception e) {
            logger.error("【请求参数解析出现异常】：{}", ExceptionUtil.logExceptionStack(e));
            return true;
        }
        return false;
    }

    /**
     * description: 签名验证
     * author sunny
     * createDate 2019-04-13 下午 4:34
     * @param reqParamMap
     * @return
     */
    public static ResponseResult checkSign(Map<String, String> reqParamMap) {
        //数据校验
        if (!Constants.APP_KEY.equals(reqParamMap.get("appKey"))) {
            return ResponseResult.buildResult(400, "appKey错误!");
        }

        //生成签名
        String sinStr = MD5SignUtil.getText(MD5SignUtil.paramsFilter(reqParamMap), "&") + "&key=" + Constants.APP_SECRET;
        String sign = MD5SignUtil.sign(sinStr).toUpperCase();
        logger.info("签名验证：待签名字符串：{}，生成的签名：{}", sinStr, sign);

        //签名验证
        if (!reqParamMap.get("sign").equals(sign)) {
            logger.info("签名验证失败，当前传入签名：{}", reqParamMap.get("sign"));
            return ResponseResult.buildResult(400, "签名验证失败!");
        }
        return null;
    }

    /**
     * 校验手机是否合法
     * @Author jy
     * @param phoneNumber
     * @return
     */
    public static boolean checkPhoneNumber(String phoneNumber) {
        Pattern p = Pattern.compile("^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$");
        Matcher m = p.matcher(phoneNumber);
        return m.matches();
    }

    /**
     * 判断是否登录
     * @Author jy
     * @param reqParamMap
     * @param jedisClient
     */
    public static void checkLogin(Map<String, String> reqParamMap,JedisClient jedisClient, PortalUserInfoService portalUserInfoService) {
        String userId = reqParamMap.get("userId");
        if (StringUtils.isBlank(userId)) {
            throw new CustomException(ResultEnum.PARAMETER_BLANK_ERROR.getCode(), String.format(ResultEnum.PARAMETER_BLANK_ERROR.getMessage(),"userId"));
        }
        String accessToken = reqParamMap.get("accessToken");
        if (StringUtils.isBlank(accessToken)) {
            throw new CustomException(ResultEnum.PARAMETER_BLANK_ERROR.getCode(), String.format(ResultEnum.PARAMETER_BLANK_ERROR.getMessage(),"accessToken"));
        }

        Object hget = jedisClient.hget("portalUser", userId);
        String s = String.valueOf(hget);
        if(!accessToken.equals(s)){
            throw new CustomException(ResultEnum.LOGIN_OUTOFDATE_ERROR);
        }

        //判断用户是否存在或禁用
        PortalUserInfo portalUserInfo = portalUserInfoService.findByUserId(userId);
        if(Objects.isNull(portalUserInfo)){
            throw new CustomException(ResultEnum.USER_NOT_EXIST_OR_FORBIDDEN);
        }
    }
}
